package com.zenithmind.library.pojo.domain;

import com.baomidou.mybatisplus.annotation.TableName;
import com.zenithmind.common.base.BaseEntity;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;

/**
 * 出版社统计信息实体
 * 遵循单一职责原则：只负责出版社统计数据的管理
 * 
 * @author ZenithMind
 * @since 2024-06-14
 */
@EqualsAndHashCode(callSuper = true)
@Data
@AllArgsConstructor
@NoArgsConstructor
@Schema(name = "出版社统计实体", description = "出版社统计信息")
@TableName("lib_publisher_statistics")
public class PublisherStatistics extends BaseEntity {

    @NotNull(message = "出版社ID不能为空")
    @Schema(description = "出版社ID")
    private String publisherId;

    @Schema(description = "出版图书数量")
    private Integer bookCount;

    @Schema(description = "总借阅次数")
    private Long totalBorrowCount;

    @Schema(description = "当前借阅次数")
    private Integer currentBorrowCount;

    @Schema(description = "平均评分")
    private BigDecimal averageRating;

    @Schema(description = "评价总数")
    private Integer totalReviewCount;

    @Schema(description = "好评数量")
    private Integer positiveReviewCount;

    @Schema(description = "差评数量")
    private Integer negativeReviewCount;

    @Schema(description = "收藏次数")
    private Long favoriteCount;

    @Schema(description = "最后出版时间")
    private LocalDateTime lastPublishTime;

    @Schema(description = "最后借阅时间")
    private LocalDateTime lastBorrowTime;

    /**
     * 增加图书数量
     */
    public void incrementBookCount() {
        bookCount = (bookCount == null ? 0 : bookCount) + 1;
        lastPublishTime = LocalDateTime.now();
    }

    /**
     * 减少图书数量
     */
    public void decrementBookCount() {
        if (bookCount != null && bookCount > 0) {
            bookCount--;
        }
    }

    /**
     * 增加借阅次数
     */
    public void incrementBorrowCount() {
        totalBorrowCount = (totalBorrowCount == null ? 0L : totalBorrowCount) + 1;
        currentBorrowCount = (currentBorrowCount == null ? 0 : currentBorrowCount) + 1;
        lastBorrowTime = LocalDateTime.now();
    }

    /**
     * 减少当前借阅次数（归还时调用）
     */
    public void decrementCurrentBorrowCount() {
        if (currentBorrowCount != null && currentBorrowCount > 0) {
            currentBorrowCount--;
        }
    }

    /**
     * 增加评价
     */
    public void addReview(Integer rating, boolean isPositive) {
        totalReviewCount = (totalReviewCount == null ? 0 : totalReviewCount) + 1;
        
        if (isPositive) {
            positiveReviewCount = (positiveReviewCount == null ? 0 : positiveReviewCount) + 1;
        } else {
            negativeReviewCount = (negativeReviewCount == null ? 0 : negativeReviewCount) + 1;
        }
        
        // 重新计算平均评分
        recalculateAverageRating();
    }

    /**
     * 移除评价
     */
    public void removeReview(boolean wasPositive) {
        if (totalReviewCount != null && totalReviewCount > 0) {
            totalReviewCount--;
            
            if (wasPositive && positiveReviewCount != null && positiveReviewCount > 0) {
                positiveReviewCount--;
            } else if (!wasPositive && negativeReviewCount != null && negativeReviewCount > 0) {
                negativeReviewCount--;
            }
            
            // 重新计算平均评分
            recalculateAverageRating();
        }
    }

    /**
     * 重新计算平均评分（需要从数据库重新查询所有评分）
     * 这里只是示例，实际应该通过服务层调用
     */
    private void recalculateAverageRating() {
        // 实际实现应该通过服务层重新计算
        // 这里只是占位符
    }

    /**
     * 增加收藏次数
     */
    public void incrementFavoriteCount() {
        favoriteCount = (favoriteCount == null ? 0L : favoriteCount) + 1;
    }

    /**
     * 减少收藏次数
     */
    public void decrementFavoriteCount() {
        if (favoriteCount != null && favoriteCount > 0) {
            favoriteCount--;
        }
    }

    /**
     * 计算好评率
     */
    public BigDecimal getPositiveRate() {
        if (totalReviewCount == null || totalReviewCount == 0) {
            return BigDecimal.ZERO;
        }
        int positive = positiveReviewCount == null ? 0 : positiveReviewCount;
        return BigDecimal.valueOf(positive)
                .divide(BigDecimal.valueOf(totalReviewCount), 4, RoundingMode.HALF_UP);
    }

    /**
     * 判断是否为大型出版社
     */
    public boolean isLargePublisher() {
        return bookCount != null && bookCount >= 100;
    }

    /**
     * 判断是否为热门出版社
     */
    public boolean isPopular() {
        long borrowCount = totalBorrowCount == null ? 0L : totalBorrowCount;
        BigDecimal rating = averageRating == null ? BigDecimal.ZERO : averageRating;
        long favorites = favoriteCount == null ? 0L : favoriteCount;
        
        return borrowCount >= 5000 || rating.compareTo(BigDecimal.valueOf(4.0)) >= 0 || favorites >= 500;
    }

    /**
     * 获取影响力分数
     */
    public BigDecimal getInfluenceScore() {
        BigDecimal bookScore = BigDecimal.valueOf(bookCount == null ? 0 : bookCount)
                .multiply(BigDecimal.valueOf(0.3));
        BigDecimal borrowScore = BigDecimal.valueOf(totalBorrowCount == null ? 0L : totalBorrowCount)
                .multiply(BigDecimal.valueOf(0.4));
        BigDecimal ratingScore = (averageRating == null ? BigDecimal.ZERO : averageRating)
                .multiply(BigDecimal.valueOf(0.2));
        BigDecimal favoriteScore = BigDecimal.valueOf(favoriteCount == null ? 0L : favoriteCount)
                .multiply(BigDecimal.valueOf(0.1));
        
        return bookScore.add(borrowScore).add(ratingScore).add(favoriteScore);
    }

    /**
     * 检查是否有图书
     */
    public boolean hasBooks() {
        return bookCount != null && bookCount > 0;
    }

    /**
     * 检查是否有借阅记录
     */
    public boolean hasBorrowHistory() {
        return totalBorrowCount != null && totalBorrowCount > 0;
    }

    /**
     * 计算平均每本书的借阅次数
     */
    public BigDecimal getAverageBorrowPerBook() {
        if (bookCount == null || bookCount == 0 || totalBorrowCount == null) {
            return BigDecimal.ZERO;
        }
        return BigDecimal.valueOf(totalBorrowCount)
                .divide(BigDecimal.valueOf(bookCount), 2, RoundingMode.HALF_UP);
    }
}
